import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

import crawler.CrawlerWeibo;

/**
 * 
 * <b>Description:</b><br/>
 * 
 * <br/>
 * <b>CreatedTime:</b>2016年3月4日 下午2:32:27<br/>
 * <br/>
 * <b>Environment:</b> <br/>
 * 
 * @author xinhui.peng(pxinhui)
 */

public class JTableCreator {

	public class TableRender extends AbstractCellEditor implements TableCellRenderer, TableCellEditor {
		class TableMouseAdapter extends MouseAdapter {

			private int tableIndex = 0;
			private TableOptItem tableOpt = null;
			public TableMouseAdapter(int index, TableOptItem opt) {
				tableIndex = index;
				tableOpt = opt;
			}
			@Override
			public void mouseClicked(MouseEvent e) {
				if (tableOpt != null && tableOpt.listener != null) {
					tableOpt.listener.onTableClick(tableIndex, getAllPosition(row), e);
				}

				super.mouseClicked(e);
			}

		}
		int row;
		int column;

		private JPanel panel = null;
		public TableRender(TableOptItem[] opt, MouseListener clickListener) {
			if (opt != null) {
				panel = new JPanel();
				for (int i = 0; i < opt.length; i++) {
					JLabel button = new JLabel(String.format(LINE_TAG, opt[i].name));
					button.setForeground(Color.BLUE);
					button.addMouseListener(new TableMouseAdapter(i, opt[i]));
					panel.add(button);
				}
			}
		}
		@Override
		public Object getCellEditorValue() {
			return "";
		}

		@Override
		public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
			this.row = row;
			this.column = column;
			// System.out.println("editor:" + value + "--row:" + row +
			// "--column:" + column);
			return panel;
		}

		@Override
		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
				boolean hasFocus, int row, int column) {
			// System.out.println("render:" + value + "--row:" + row +
			// "--column:" + column);
			return panel;
		}
	}

	private DefaultTableModel model;
	private JTable table;
	public JTable creatTable(final String[] title, int[] maxWidth, int[] minWidth,
			final OnTableSelectListener onTableSelectListener, final TableOptItem[] opt) {

		model = new DefaultTableModel(title, 0) {
			@Override
			public boolean isCellEditable(int row, int column) {

				if (opt == null) {
					return false;
				}
				if (column == title.length - 1) {
					return super.isCellEditable(row, column);
				}
				return false;

			}
		};
		table = new JTable(model);
		table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
		table.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() == 2) {
					int row = table.getSelectedRow();

					if (onTableSelectListener != null) {
						onTableSelectListener.onTableSelect(getAllPosition(row), e);
					}
				}
				super.mouseClicked(e);
			}
		});
		if (maxWidth != null) {
			for (int i = 0; i < maxWidth.length; i++) {
				if (maxWidth[i] > 0) {
					// table.getColumnModel().getColumn(i).setMaxWidth(width[i]);
					table.getColumnModel().getColumn(i).setMaxWidth(maxWidth[i]);
				}
			}
		}
		if (minWidth != null) {
			for (int i = 0; i < minWidth.length; i++) {
				if (minWidth[i] > 0) {
					// table.getColumnModel().getColumn(i).setMaxWidth(width[i]);
					table.getColumnModel().getColumn(i).setMinWidth(minWidth[i]);
				}
			}
		}
		table.setRowHeight(25);

		if (opt != null) {
			table.getColumnModel().getColumn(table.getColumnCount() - 1).setCellEditor(new TableRender(opt, null));
			table.getColumnModel().getColumn(table.getColumnCount() - 1).setCellRenderer(new TableRender(opt, null));
		}
		RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
		table.setRowSorter(sorter);

		return table;
	}
	public int getAllPosition(int row) {
		return row + tablePageSize * (prePage - 1);
	}
	private int prePage = 1;
	private int currentPage = 1;
	private final String LINE_TAG = "<HTML><B><U>%s</U></B></HTML>";
	private JLabel preLabel;
	private int preIndex;
	private int preAllIndex;
	private String[] middle;
	private JPanel pagePanel;
	private OnPageChangeListener pageListener;
	public JPanel createPage(JPanel parentPanel, final int startPage, final int endPage, final int showLen,
			final OnPageChangeListener listener) {
//		this.pagePanel = pagePanel;
		this.pageListener = listener;
		if(pagePanel==null){
			pagePanel = new JPanel();
			pagePanel.setLayout(new FlowLayout());
			parentPanel.add(pagePanel, BorderLayout.SOUTH);
		}
		final String[] start = {"首页", "上一页"};
		prePage = startPage;
		final String[] middleAll = new String[endPage - startPage + 1];
		for (int i = startPage; i <= endPage; i++) {
			middleAll[i - 1] = Integer.toString(i);
		}
		if (middleAll.length > showLen) {
			middle = new String[showLen];
			preAllIndex = 0;
			System.arraycopy(middleAll, 0, middle, 0, showLen);
		} else {
			middle = middleAll;
		}
		final String[] end = {"下一页", "最后一页"};

		final List<JLabel> labels = new ArrayList<JLabel>(start.length + middle.length + end.length);
		JLabel btn = new JLabel();
		btn.setText(start[0]);
		btn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {

				if (Integer.valueOf(middle[0]) != Integer.valueOf(middleAll[0])) {
					System.arraycopy(middleAll, 0, middle, 0, showLen);
					preAllIndex = 0;
					notifyPanel(labels, preIndex);
				}
				if (prePage == Integer.valueOf(middle[0])) {
					return;
				}
				JLabel label = labels.get(2);
				preLabel.setText(middle[preIndex]);
				label.setText(String.format(LINE_TAG, middle[0]));
				preLabel = label;
				preIndex = 0;
				prePage = Integer.valueOf(middle[0]);
				onPageChange(0, prePage);
				super.mouseClicked(e);
			}
		});
		labels.add(btn);
		pagePanel.add(btn);

		btn = new JLabel();
		btn.setText(start[1]);
		btn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (prePage <= Integer.valueOf(middle[0])) {
					if (Integer.valueOf(middle[0]) == Integer.valueOf(middleAll[0])) {
						return;
					}

					final int sub = preAllIndex - showLen;
					int srcPos = sub < 0 ? 0 : preAllIndex - showLen;
					System.arraycopy(middleAll, srcPos, middle, 0, showLen);
					// notifyPanel(labels, preIndex);
					preAllIndex = srcPos;
					if (sub < 0) {
						preIndex = (showLen + sub) % showLen;
					}
					prePage = Integer.valueOf(middle[(preIndex - 1) % showLen]);
				} else {
					prePage = prePage - 1;
				}

				int curIndex = (preIndex - 1 + showLen) % showLen;
				JLabel label = labels.get(curIndex + 2);
				// preLabel.setText(middle[preIndex]);
				notifyPanel(labels, preIndex);
				label.setText(String.format(LINE_TAG, middle[curIndex]));
				preLabel = label;
				preIndex = curIndex;
				onPageChange(preIndex, prePage);
				super.mouseClicked(e);
			}
		});
		labels.add(btn);
		pagePanel.add(btn);

		for (int i = 0; i < middle.length; i++) {
			final int index = i;
			btn = new JLabel();
			if (index == 0) {
				preLabel = btn;
				preIndex = index;
				btn.setText(String.format(LINE_TAG, middle[index]));
			} else {
				btn.setText(middle[index]);
			}
			btn.addMouseListener(new MouseAdapter() {
				@Override
				public void mouseClicked(MouseEvent e) {
					JLabel label = (JLabel) e.getComponent();
					label.setText(String.format(LINE_TAG, middle[index]));
					preLabel.setText(middle[preIndex]);
					preLabel = label;
					preIndex = index;
					prePage = Integer.valueOf(middle[index]);
					onPageChange(preIndex, prePage);
					super.mouseClicked(e);
				}
			});
			labels.add(btn);
			pagePanel.add(btn);
		}

		btn = new JLabel();
		btn.setText(end[0]);
		btn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				int add = 0;
				if (prePage >= Integer.valueOf(middle[middle.length - 1])) {
					if (Integer.valueOf(middle[middle.length - 1]) == Integer.valueOf(middleAll[middleAll.length - 1])) {

						return;
					}

					add = preAllIndex + showLen + showLen - middleAll.length;
					int srcPos = add > 0 ? middleAll.length - showLen : preAllIndex + showLen;
					System.arraycopy(middleAll, srcPos, middle, 0, showLen);
					// notifyPanel(labels, preIndex);
					preAllIndex = srcPos;
					if (add > 0) {
						preIndex = (preIndex + add) % showLen;
					}
					prePage = Integer.valueOf(middle[(preIndex + 1) % showLen]);
				} else {
					prePage = prePage + 1;
				}

				int curIndex = (preIndex + 1) % showLen;
				JLabel label = labels.get(curIndex + 2);
				// preLabel.setText(middle[preIndex]);
				notifyPanel(labels, preIndex);
				label.setText(String.format(LINE_TAG, middle[curIndex]));
				preLabel = label;
				preIndex = curIndex;
				onPageChange(preIndex, prePage);
				super.mouseClicked(e);
			}
		});
		labels.add(btn);
		pagePanel.add(btn);

		btn = new JLabel();
		btn.setText(end[1]);
		btn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (Integer.valueOf(middle[middle.length - 1]) != Integer.valueOf(middleAll[middleAll.length - 1])) {
					int srcPos = middleAll.length - showLen;
					System.arraycopy(middleAll, srcPos, middle, 0, showLen);
					preAllIndex = srcPos;
					notifyPanel(labels, preIndex);
				}
				if (prePage == Integer.valueOf(middle[middle.length - 1])) {
					return;
				}
				JLabel label = labels.get(middle.length + 1);
				preLabel.setText(middle[preIndex]);
				label.setText(String.format(LINE_TAG, middle[middle.length - 1]));
				preLabel = label;
				preIndex = middle.length - 1;
				prePage = Integer.valueOf(middle[middle.length - 1]);
				onPageChange(preIndex, prePage);
				super.mouseClicked(e);
			}
		});
		labels.add(btn);
		pagePanel.add(btn);
		return pagePanel;
	}
	private List<Vector<String>> tableData = new ArrayList<Vector<String>>();
	public List<Vector<String>> getTableData() {
		return tableData;
	}
	private int tablePageSize = TableConfig.PAGE_SIZE;
	/**
	 * 设置数据
	 * 
	 * @param data
	 * @param pageSize
	 * @return
	 */
	public int setTableData(List<Vector<String>> data, int pageSize) {

		if (data == null || data.isEmpty()) {
			return 0;
		}
		tableData = data;
		tablePageSize = pageSize > TableConfig.PAGE_SIZE ? pageSize : TableConfig.PAGE_SIZE;
		tablePageSize = tableData.size() < tablePageSize ? tableData.size() : tablePageSize;
		final int size = tableData.size();

		model.setRowCount(0);
		if (tablePageSize > 0) {
			String[] array = new String[tableData.get(0).size()];
			for (int i = 0; i < tablePageSize; i++) {
				array = tableData.get(i).toArray(array);
				model.addRow(array);
			}
		}
		return size / tablePageSize + 1;

	}
	void notifyPageChange(int index, int pageValue) {
		if (tableData.isEmpty()) {
			return;
		}
		final int srcPos = (pageValue - 1) * tablePageSize;
		DefaultTableModel m = (DefaultTableModel) table.getModel();
		m.setRowCount(0);
		if (tablePageSize > 0) {
			String[] array = new String[tableData.get(0).size()];
			for (int i = 0; i < tablePageSize; i++) {
				if (i + srcPos < tableData.size()) {
					// System.out.println(i + srcPos + ":" + tableData.get(i +
					// srcPos).get(3));
					array = tableData.get(i + srcPos).toArray(array);
					model.addRow(array);

				}
			}
		}
		table.updateUI();
	}
	void notifyPanel(List<JLabel> labels, int curIndex) {
		for (int i = 0; i < middle.length; i++) {
			labels.get(i + 2).setText(middle[i]);
		}
	}
	public void setPage(int startPage, int endPage, int maxPageSize) {
		if (this.pagePanel == null) {
			throw new NullPointerException("分页未初始化！！！");
		}
		pagePanel.removeAll();
		createPage(pagePanel, startPage, endPage, maxPageSize, pageListener);

	}
	void onPageChange(int index, int pageValue) {
		notifyPageChange(index, pageValue);
		if (pageListener != null) {
			pageListener.onPageChange(index, pageValue);
		}
	}
	public static class TableOptItem {
		String name;
		OnTableClickListener listener;
		public TableOptItem(String name, OnTableClickListener listener) {
			super();
			this.name = name;
			this.listener = listener;
		}

	}
	public interface OnPageChangeListener {
		public void onPageChange(int index, int pageValue);
	}

	public interface OnTableClickListener {
		public void onTableClick(int optIndex, int allPositon, MouseEvent event);
	}
	public interface OnTableSelectListener {
		public void onTableSelect(int allPositon, MouseEvent event);
	}
	public void main(String[] args) {
		CrawlerWeibo webo;
	}

}
